package com.uduemc.biso.node.module.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.uduemc.biso.node.core.common.sysconfig.ProductSysConfig;
import com.uduemc.biso.node.core.dto.FeignSystemDataInfos;
import com.uduemc.biso.node.core.dto.FeignSystemTotal;
import com.uduemc.biso.node.core.entities.SCategories;
import com.uduemc.biso.node.core.entities.SProduct;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.core.utils.SystemConfigUtil;
import com.uduemc.biso.node.module.mapper.SProductMapper;
import com.uduemc.biso.node.module.service.SCategoriesService;
import com.uduemc.biso.node.module.service.SProductService;
import com.uduemc.biso.node.module.service.SSystemService;

import cn.hutool.core.collection.CollUtil;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service
public class SProductServiceImpl implements SProductService {

	// private final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private SProductMapper sProductMapper;

	@Autowired
	private SSystemService sSystemServiceImpl;

	@Autowired
	private SCategoriesService sCategoriesServiceImpl;

	@Override
	public SProduct insertAndUpdateCreateAt(SProduct sProduct) {
		sProductMapper.insert(sProduct);
		SProduct findOne = findOne(sProduct.getId());
		Date createAt = sProduct.getCreateAt();
		if (createAt != null) {
			sProductMapper.updateCreateAt(findOne.getId(), createAt, SProduct.class);
		}
		return findOne;
	}

	@Override
	public SProduct insert(SProduct sProduct) {
		sProductMapper.insert(sProduct);
		return findOne(sProduct.getId());
	}

	@Override
	public SProduct insertSelective(SProduct sProduct) {
		sProductMapper.insertSelective(sProduct);
		return findOne(sProduct.getId());
	}

	@Override
	public SProduct updateById(SProduct sProduct) {
		sProductMapper.updateByPrimaryKeySelective(sProduct);
		return findOne(sProduct.getId());
	}

	@Override
	public SProduct findOne(Long id) {
		return sProductMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<SProduct> findAll(Pageable pageable) {
		return findAll(pageable.getPageNumber(), pageable.getPageSize());
	}

	@Override
	public List<SProduct> findAll(int pageNum, int pageSize) {
		PageHelper.startPage(pageNum, pageSize);
		return sProductMapper.selectAll();
	}

	@Override
	public void deleteById(Long id) {
		sProductMapper.deleteByPrimaryKey(id);
	}

	@Override
	public int deleteByHostSiteId(long hostId, long siteId) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		return sProductMapper.deleteByExample(example);
	}

	@Override
	public SProduct updateAllById(SProduct sProduct) {
		sProductMapper.updateByPrimaryKey(sProduct);
		return findOne(sProduct.getId());
	}

	@Override
	public SProduct findByHostSiteSystemIdAndId(long id, long hostId, long siteId, long systemId) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("id", id);
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);
		List<SProduct> selectByExample = sProductMapper.selectByExample(example);
		if (CollectionUtils.isEmpty(selectByExample)) {
			return null;
		}
		return selectByExample.get(0);
	}

	@Override
	public SProduct findByHostSiteIdAndId(long id, long hostId, long siteId) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("id", id);
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		List<SProduct> selectByExample = sProductMapper.selectByExample(example);
		if (CollectionUtils.isEmpty(selectByExample)) {
			return null;
		}
		return selectByExample.get(0);
	}

	@Override
	public boolean deleteBySystemId(long hostId, long siteId, long systemId) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);
		int selectCountByExample = sProductMapper.selectCountByExample(example);
		if (selectCountByExample < 1) {
			return true;
		}
		return sProductMapper.deleteByExample(example) == selectCountByExample;
	}

	@Override
	public int totalByHostId(long hostId) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		int total = sProductMapper.selectCountByExample(example);
		return total;
	}

	@Override
	public int totalByFeignSystemTotal(FeignSystemTotal feignSystemTotal) {
		long hostId = feignSystemTotal.getHostId();
		long siteId = feignSystemTotal.getSiteId();
		long systemId = feignSystemTotal.getSystemId();
		short isShow = feignSystemTotal.getIsShow();
		short isTop = feignSystemTotal.getIsTop();
		short isRefuse = feignSystemTotal.getIsRefuse();

		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		if (hostId > (long) -1) {
			criteria.andEqualTo("hostId", hostId);
		}
		if (siteId > (long) -1) {
			criteria.andEqualTo("siteId", siteId);
		}
		if (systemId > (long) -1) {
			criteria.andEqualTo("systemId", systemId);
		}

		if (isShow > (short) -1) {
			criteria.andEqualTo("isShow", isShow);
		}
		if (isTop > (short) -1) {
			criteria.andEqualTo("isTop", isTop);
		}
		if (isRefuse > (short) -1) {
			criteria.andEqualTo("isRefuse", isRefuse);
		}

		return sProductMapper.selectCountByExample(example);
	}

	@Override
	public int totalByHostSiteSystemId(long hostId, long siteId, long systemId) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);
		int total = sProductMapper.selectCountByExample(example);
		return total;
	}

	@Override
	public int totalOkByHostSiteSystemId(long hostId, long siteId, long systemId) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);
		criteria.andEqualTo("isRefuse", (short) 0);
		int total = sProductMapper.selectCountByExample(example);
		return total;
	}

	@Override
	public List<SProduct> findOkByHostSiteSystemIdAndIds(List<Long> ids, long hostId, long siteId, long systemId) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andIn("id", ids);
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);
		criteria.andEqualTo("isShow", (short) 1);
		criteria.andEqualTo("isRefuse", (short) 0);
		List<SProduct> selectByExample = sProductMapper.selectByExample(example);
		if (CollectionUtils.isEmpty(selectByExample)) {
			return null;
		}
		return selectByExample;
	}

	@Override
	public PageInfo<SProduct> findPageInfoAll(long hostId, long siteId, int pageNum, int pageSize) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		PageHelper.startPage(pageNum, pageSize);
		List<SProduct> listSProduct = sProductMapper.selectByExample(example);
		PageInfo<SProduct> result = new PageInfo<>(listSProduct);
		return result;
	}

	@Override
	public PageInfo<SProduct> findPageInfoAll(long hostId, long siteId, long systemId, int pageNum, int pageSize) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);
		PageHelper.startPage(pageNum, pageSize);
		List<SProduct> listSProduct = sProductMapper.selectByExample(example);
		PageInfo<SProduct> result = new PageInfo<>(listSProduct);
		return result;
	}

	@Override
	public SProduct findPrev(SProduct sProduct, long categoryId) {
		if (sProduct == null) {
			return null;
		}
		Long hostId = sProduct.getHostId();
		Long siteId = sProduct.getSiteId();
		Long systemId = sProduct.getSystemId();
		SSystem sSystem = sSystemServiceImpl.findSSystemByIdHostSiteId(systemId, hostId, siteId);
		if (sSystem == null) {
			return null;
		}

		List<SCategories> sCategoriesList = new ArrayList<>();
		if (categoryId > 0) {
			SCategories findOne = sCategoriesServiceImpl.findByHostSiteSystemIdAndId(hostId, siteId, systemId, categoryId);
			sCategoriesList.add(findOne);
			List<SCategories> findByAncestors = sCategoriesServiceImpl.findByAncestors(categoryId);
			sCategoriesList.addAll(findByAncestors);
			sCategoriesList = CollUtil.distinct(sCategoriesList);
		}

		String sCategoriesIds = null;
		if (CollUtil.isNotEmpty(sCategoriesList)) {
			List<Long> ids = new ArrayList<>(sCategoriesList.size());
			for (SCategories sCategories : sCategoriesList) {
				ids.add(sCategories.getId());
			}
			sCategoriesIds = CollUtil.join(ids, ",");
		}

		ProductSysConfig productSysConfig = SystemConfigUtil.productSysConfig(sSystem);
		int orderby = productSysConfig.getList().findOrderby();
		if (orderby == 1) {
			return prevOrderBy1(sProduct, sCategoriesIds);
		} else if (orderby == 2) {
			return prevOrderBy2(sProduct, sCategoriesIds);
		} else if (orderby == 3) {
			return prevOrderBy3(sProduct, sCategoriesIds);
		} else if (orderby == 4) {
			return prevOrderBy4(sProduct, sCategoriesIds);
		} else {
			return prevOrderBy1(sProduct, sCategoriesIds);
		}

	}

	public SProduct prevOrderBy1(SProduct aProduct, String sCategoriesIds) {
		Long id = aProduct.getId();
		Long hostId = aProduct.getHostId();
		Long siteId = aProduct.getSiteId();
		Long systemId = aProduct.getSystemId();
		short top = aProduct.getIsTop() == null ? 0 : aProduct.getIsTop().shortValue();
		int orderNum = aProduct.getOrderNum() == null ? 1 : aProduct.getOrderNum().intValue();

		SProduct sProduct = sProductMapper.prevData1Id(hostId, siteId, systemId, top, orderNum, id, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.prevData1OrderNum(hostId, siteId, systemId, top, orderNum, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.prevData1Top(hostId, siteId, systemId, top, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		return null;
	}

	public SProduct prevOrderBy2(SProduct aProduct, String sCategoriesIds) {
		Long id = aProduct.getId();
		Long hostId = aProduct.getHostId();
		Long siteId = aProduct.getSiteId();
		Long systemId = aProduct.getSystemId();
		short top = aProduct.getIsTop() == null ? 0 : aProduct.getIsTop().shortValue();
		int orderNum = aProduct.getOrderNum() == null ? 1 : aProduct.getOrderNum().intValue();

		SProduct sProduct = sProductMapper.prevData2Id(hostId, siteId, systemId, top, orderNum, id, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.prevData2OrderNum(hostId, siteId, systemId, top, orderNum, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.prevData2Top(hostId, siteId, systemId, top, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		return null;
	}

	public SProduct prevOrderBy3(SProduct aProduct, String sCategoriesIds) {
		Long id = aProduct.getId();
		Long hostId = aProduct.getHostId();
		Long siteId = aProduct.getSiteId();
		Long systemId = aProduct.getSystemId();
		short top = aProduct.getIsTop() == null ? 0 : aProduct.getIsTop().shortValue();
		Long releasedUTime = aProduct.getReleasedAt() == null ? aProduct.getCreateAt().getTime() : aProduct.getReleasedAt().getTime();
		releasedUTime = releasedUTime / 1000;

		SProduct sProduct = sProductMapper.prevData3Id(hostId, siteId, systemId, top, releasedUTime, id, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.prevData3OrderNum(hostId, siteId, systemId, top, releasedUTime, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.prevData3Top(hostId, siteId, systemId, top, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		return null;
	}

	public SProduct prevOrderBy4(SProduct aProduct, String sCategoriesIds) {
		Long id = aProduct.getId();
		Long hostId = aProduct.getHostId();
		Long siteId = aProduct.getSiteId();
		Long systemId = aProduct.getSystemId();
		short top = aProduct.getIsTop() == null ? 0 : aProduct.getIsTop().shortValue();
		Long releasedUTime = aProduct.getReleasedAt() == null ? aProduct.getCreateAt().getTime() : aProduct.getReleasedAt().getTime();
		releasedUTime = releasedUTime / 1000;

		SProduct sProduct = sProductMapper.prevData4Id(hostId, siteId, systemId, top, releasedUTime, id, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.prevData4OrderNum(hostId, siteId, systemId, top, releasedUTime, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.prevData4Top(hostId, siteId, systemId, top, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		return null;
	}

	@Override
	public SProduct findNext(SProduct sProduct, long categoryId) {
		if (sProduct == null) {
			return null;
		}
		Long hostId = sProduct.getHostId();
		Long siteId = sProduct.getSiteId();
		Long systemId = sProduct.getSystemId();
		SSystem sSystem = sSystemServiceImpl.findSSystemByIdHostSiteId(systemId, hostId, siteId);
		if (sSystem == null) {
			return null;
		}

		List<SCategories> sCategoriesList = new ArrayList<>();
		if (categoryId > 0) {
			SCategories findOne = sCategoriesServiceImpl.findByHostSiteSystemIdAndId(hostId, siteId, systemId, categoryId);
			sCategoriesList.add(findOne);
			List<SCategories> findByAncestors = sCategoriesServiceImpl.findByAncestors(categoryId);
			sCategoriesList.addAll(findByAncestors);
			sCategoriesList = CollUtil.distinct(sCategoriesList);
		}

		String sCategoriesIds = null;
		if (CollUtil.isNotEmpty(sCategoriesList)) {
			List<Long> ids = new ArrayList<>(sCategoriesList.size());
			for (SCategories sCategories : sCategoriesList) {
				ids.add(sCategories.getId());
			}
			sCategoriesIds = CollUtil.join(ids, ",");
		}

		ProductSysConfig productSysConfig = SystemConfigUtil.productSysConfig(sSystem);
		int orderby = productSysConfig.getList().findOrderby();
		if (orderby == 1) {
			return nextOrderBy1(sProduct, sCategoriesIds);
		} else if (orderby == 2) {
			return nextOrderBy2(sProduct, sCategoriesIds);
		} else if (orderby == 3) {
			return nextOrderBy3(sProduct, sCategoriesIds);
		} else if (orderby == 4) {
			return nextOrderBy4(sProduct, sCategoriesIds);
		} else {
			return nextOrderBy1(sProduct, sCategoriesIds);
		}
	}

	public SProduct nextOrderBy1(SProduct aProduct, String sCategoriesIds) {
		Long id = aProduct.getId();
		Long hostId = aProduct.getHostId();
		Long siteId = aProduct.getSiteId();
		Long systemId = aProduct.getSystemId();
		short top = aProduct.getIsTop() == null ? 0 : aProduct.getIsTop().shortValue();
		int orderNum = aProduct.getOrderNum() == null ? 1 : aProduct.getOrderNum().intValue();

		SProduct sProduct = sProductMapper.nextData1Id(hostId, siteId, systemId, top, orderNum, id, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.nextData1OrderNum(hostId, siteId, systemId, top, orderNum, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.nextData1Top(hostId, siteId, systemId, top, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		return null;
	}

	public SProduct nextOrderBy2(SProduct aProduct, String sCategoriesIds) {
		Long id = aProduct.getId();
		Long hostId = aProduct.getHostId();
		Long siteId = aProduct.getSiteId();
		Long systemId = aProduct.getSystemId();
		short top = aProduct.getIsTop() == null ? 0 : aProduct.getIsTop().shortValue();
		int orderNum = aProduct.getOrderNum() == null ? 1 : aProduct.getOrderNum().intValue();

		SProduct sProduct = sProductMapper.nextData2Id(hostId, siteId, systemId, top, orderNum, id, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.nextData2OrderNum(hostId, siteId, systemId, top, orderNum, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.nextData2Top(hostId, siteId, systemId, top, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		return null;
	}

	public SProduct nextOrderBy3(SProduct aProduct, String sCategoriesIds) {
		Long id = aProduct.getId();
		Long hostId = aProduct.getHostId();
		Long siteId = aProduct.getSiteId();
		Long systemId = aProduct.getSystemId();
		short top = aProduct.getIsTop() == null ? 0 : aProduct.getIsTop().shortValue();
		Long releasedUTime = aProduct.getReleasedAt() == null ? aProduct.getCreateAt().getTime() : aProduct.getReleasedAt().getTime();
		releasedUTime = releasedUTime / 1000;

		SProduct sProduct = sProductMapper.nextData3Id(hostId, siteId, systemId, top, releasedUTime, id, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.nextData3OrderNum(hostId, siteId, systemId, top, releasedUTime, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.nextData3Top(hostId, siteId, systemId, top, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		return null;
	}

	public SProduct nextOrderBy4(SProduct aProduct, String sCategoriesIds) {
		Long id = aProduct.getId();
		Long hostId = aProduct.getHostId();
		Long siteId = aProduct.getSiteId();
		Long systemId = aProduct.getSystemId();
		short top = aProduct.getIsTop() == null ? 0 : aProduct.getIsTop().shortValue();
		Long releasedUTime = aProduct.getReleasedAt() == null ? aProduct.getCreateAt().getTime() : aProduct.getReleasedAt().getTime();
		releasedUTime = releasedUTime / 1000;

		SProduct sProduct = sProductMapper.nextData4Id(hostId, siteId, systemId, top, releasedUTime, id, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.nextData4OrderNum(hostId, siteId, systemId, top, releasedUTime, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		sProduct = sProductMapper.nextData4Top(hostId, siteId, systemId, top, sCategoriesIds);
		if (sProduct != null) {
			return sProduct;
		}

		return null;
	}

	@Override
	public List<SProduct> findInfosByHostSiteSystemAndIds(FeignSystemDataInfos feignSystemDataInfos) {
		long hostId = feignSystemDataInfos.getHostId();
		long siteId = feignSystemDataInfos.getSiteId();
		long systemId = feignSystemDataInfos.getSystemId();
		short isRefuse = feignSystemDataInfos.getIsRefuse();
		List<Long> ids = feignSystemDataInfos.getIds();

		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		if (hostId > 0) {
			criteria.andEqualTo("hostId", hostId);
		}
		if (siteId > -1) {
			criteria.andEqualTo("siteId", siteId);
		}
		if (systemId > 0) {
			criteria.andEqualTo("systemId", systemId);
		}
		if (isRefuse > -1) {
			criteria.andEqualTo("isRefuse", isRefuse);
		}
		if (CollUtil.isNotEmpty(ids)) {
			criteria.andIn("id", ids);
		}

		PageHelper.startPage(1, 200);
		List<SProduct> listSArticle = sProductMapper.selectByExample(example);
		return listSArticle;
	}

	@Override
	public SProduct findByIdAndHostSiteSystemId(long id, long hostId, long siteId, long systemId) {
		Example example = new Example(SProduct.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("id", id);
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);
		return sProductMapper.selectOneByExample(example);
	}

}
